import time

from appium import webdriver
import numpy as np
import cv2 as cv
import pymysql

mysql_connect = pymysql.connect(
    host="localhost",
    user="root",
    passwd="123456",
    db="baidu_idiom",
    charset='utf8',
    cursorclass=pymysql.cursors.DictCursor
)
cursor = mysql_connect.cursor()


def get_driver():
    """
    获取设备
    :return:
    """
    desired_caps = {
        'platformName': 'Android',
        'appPackage': 'com.yiqunkeji.sjxb',
        'appActivity': 'com.tianyuan.sjstudy.modules.ppx.ui.SplashActivity',
        'noReset': True,
        'skipServerInstallation': True,
        'skipDeviceInitialization': True,
        'newCommandTimeout': 80
    }

    return webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)


def skip_ad(driver):
    """
    跳过启动页广告
    """
    ele_ad = driver.find_element_by_id('com.yiqunkeji.sjxb:id/tt_splash_skip_btn')
    ele_ad.click()
    time.sleep(0.5)


def get_position(location, size):
    """
    获取元素中心位置坐标
    :param location:
    :param size:
    :return:
    """
    # 根据元素位置和元素宽高获取元素中心位置坐标
    x = location['x'] + size['width'] / 2
    y = location['y'] + size['height'] / 2

    return x, y


def get_positions(location, size, fix=0):
    """
    获取元素左上角 和右下角坐标
    :param location:
    :param size:
    :param fix:
    :return:
    """
    # 根据元素位置和元素宽高获取元素中心位置坐标
    x = location['x'] + size['width'] - fix
    y = location['y'] + size['height'] - fix

    return [location['x'] + fix, location['y'] + fix, x, y]


def iv_start(driver):
    """
    点击下一关
    """
    try:

        element = driver.find_element_by_id('com.yiqunkeji.sjxb:id/iv_start')
        # x, y = get_position(element.location, element.size)
        # driver.tap([(x, y)])
        element.click()
        time.sleep(2)

        # 获取鸡腿
        iv_play(driver, True)
    except:
        pass


def double_coin(driver):
    try:
        ele = driver.find_element_by_id('com.yiqunkeji.sjxb:id/tv_guide_coin_text2')

        ele.click()

        close_ad(driver)

    except:
        return


def get_idioms(question_str_np):
    """
    获取成语
    :param question_str_np:
    :return:
    """
    # print(question_str_np)
    idioms = []
    for h in range(0, 9):
        for w in range(0, 9):
            has_idiom = True
            idiom = []
            for i in range(0, 4):
                if w + i < 9 and question_str_np[h][w + i] != '0':
                    # print(question_str_np[h][w + i])
                    idiom.append(question_str_np[h][w + i])
                else:
                    has_idiom = False
            if has_idiom:
                idioms.append(idiom)
            has_idiom = True
            idiom = []
            for j in range(0, 4):
                if h + j < 9 and question_str_np[h + j][w] != '0':
                    idiom.append(question_str_np[h + j][w])
                else:
                    has_idiom = False
            if has_idiom:
                idioms.append(idiom)
    return idioms


def search_idiom_by_mysql(data):
    """
    通过数据库查询成语
    :param data:
    :return:
    """
    sql_where = []

    if data[0].find("-") == -1:
        sql_where.append(" q1 = '" + str(data[0]) + "'")
    if data[1].find("-") == -1:
        sql_where.append(" q2 = '" + str(data[1]) + "'")
    if data[2].find("-") == -1:
        sql_where.append(" q3 = '" + str(data[2]) + "'")
    if data[3].find("-") == -1:
        sql_where.append(" q4 = '" + str(data[3]) + "'")
    if len(sql_where) > 1:
        sql_where_str = " and ".join(sql_where)
    elif len(sql_where) == 1:
        sql_where_str = sql_where[0]
    else:
        return []

    sql = "select concat(q1, q2, q3, q4) as res from idiom_with_four_words where " + sql_where_str
    res = cursor.execute(sql)
    res_data = cursor.fetchmany(res)
    if len(res_data) > 0:
        tmp_data = []
        for d in res_data:
            tmp_data.append(d['res'])
        return tmp_data
    else:
        return []


def get_unknown_str_num(idiom):
    """
    获取成语中未知字符的个数
    :param idiom:
    :return:
    """
    i = 0
    for s in idiom:
        if s.find('-') != -1:
            i += 1
    return i


def idioms_sort(idioms):
    """
    成语简单排序, 优先查询字符个数较多的成语
    :param idioms:
    :return:
    """
    new_idioms = [[], [], [], [], []]

    for idiom in idioms:
        n = get_unknown_str_num(idiom)
        new_idioms[n].append(idiom)
    return new_idioms[0] + new_idioms[1] + new_idioms[2] + new_idioms[3] + new_idioms[4]


def answer_question(driver):
    img = screenshot(driver)

    question_str_np, question_str_position_np = get_question_str(driver, img)
    answer_str_np, answer_str_position_np = get_answer_str(driver)
    # print(answer_str_np)
    # print(answer_str_position_np)
    # exit(0)
    # print(answer_str_position_np)
    idioms = get_idioms(question_str_np)
    idioms = idioms_sort(idioms)
    # print(idioms)
    for l in range(0, len(idioms)):
        for idiom in idioms:
            if get_unknown_str_num(idiom) == 0:
                continue
            sear_res = search_idiom_by_mysql(idiom)

            is_find, res, str_pos, str_index, answer_str = find_right_idiom(sear_res, idiom, answer_str_np)
            # print(res, idiom, str_pos, answer_str)
            if is_find:
                for i in range(0, len(str_pos)):
                    h_w = str_pos[i].split('-')
                    h = int(h_w[0])
                    w = int(h_w[1])
                    que_pos = question_str_position_np[h][w].split('-')
                    q_x = int(float(que_pos[0]))
                    q_y = int(float(que_pos[1]))
                    # print(str_pos, q_x, q_y)
                    driver.tap([(q_x, q_y)])
                    time.sleep(0.3)

                    ans = answer_str[i]
                    ans_index = answer_str_np.index(ans)
                    ans_pos = answer_str_position_np[ans_index].split('-')
                    a_x = int(float(ans_pos[0]))
                    a_y = int(float(ans_pos[1]))
                    # print(ans, ans_index, a_x, a_y)
                    answer_str_np[ans_index] = ''
                    driver.tap([(a_x, a_y)])
                    time.sleep(0.3)

                    # 替换成语中已找到的字符
                    for idi in idioms:
                        if str_pos[i] in idi:
                            ind = idi.index(str_pos[i])
                            idi[ind] = answer_str[i]
                    # print(idioms)
                    # exit(1)
                break
            else:
                res = False

    time.sleep(5)


def find_right_idiom(sear_res, idiom, answer_str_np):
    str_index = []
    answer_str = []
    str_pos = []
    for i in range(0, 4):
        if idiom[i].find('-') != -1:
            str_index.append(i)
            str_pos.append(idiom[i])
    for res in sear_res:
        is_right = True
        for i in str_index:
            if res[i] not in answer_str_np:
                is_right = False
                break
            answer_str.append(res[i])
        if is_right:
            return True, res, str_pos, str_index, answer_str
        answer_str = []
    return False, [], str_pos, str_index, answer_str


def get_question_str(driver, img):
    question_str_list = []
    question_str_position = []

    ele_que_list = driver.find_element_by_id('com.yiqunkeji.sjxb:id/list')
    ele_ques = ele_que_list.find_elements_by_class_name('android.widget.LinearLayout')

    for i in range(0, 162):
        if i % 2 == 1:
            try:
                que_str = ele_ques[i].find_element_by_id("com.yiqunkeji.sjxb:id/tv_text").text
            except:
                x1, y1, x2, y2 = get_positions(ele_ques[i].location, ele_ques[i].size, 15)
                tmp_mean = np.mean(img[y1:y2, x1:x2])
                if tmp_mean < 105:
                    index = i // 2
                    h = index // 9
                    w = index % 9
                    que_str = str(h) + '-' + str(w)
                else:
                    que_str = '0'

            x, y = get_position(ele_ques[i].location, ele_ques[i].size)
            question_str_list.append(que_str)
            question_str_position.append(str(x) + '-' + str(y))

    question_str_np = np.array(question_str_list).reshape(9, 9)
    question_str_position_np = np.array(question_str_position).reshape(9, 9)
    # print(question_str_np)
    return question_str_np, question_str_position_np


def get_answer_str(driver):
    """
    获取答案字符
    :param driver:
    :return:
    """
    answer_str_list = []
    answer_str_position = []

    ele_answer_list = driver.find_element_by_id('com.yiqunkeji.sjxb:id/list_answer')
    ele_answer = ele_answer_list.find_elements_by_class_name('android.widget.TextView')
    # for ele in ele_answer:
    for i in range(0, len(ele_answer)):
        answer_str_list.append(ele_answer[i].text)
        x, y = get_position(ele_answer[i].location, ele_answer[i].size)
        # print(ele_answer[i].text, str(x), str(y))
        answer_str_position.append(str(x) + '-' + str(y))
    # print(answer_str_list, answer_str_position)
    return answer_str_list, answer_str_position


def screenshot(driver):
    tmp_screenshot_path = "./current.png"

    driver.save_screenshot(tmp_screenshot_path)

    return cv.imread(tmp_screenshot_path)


def close_ad(driver):
    while True:
        try:
            time.sleep(65)
            ele_ad_close = driver.find_element_by_class_name('android.widget.ImageView')
            ele_ad_close.click()
            time.sleep(1)
            break
        except:
            pass


def iv_play(driver, need_start=False):
    try:
        ele_play = driver.find_element_by_id('com.yiqunkeji.sjxb:id/iv_play')
        ele_play.click()

        close_ad(driver)

        ele_iv_ok = driver.find_element_by_id('com.yiqunkeji.sjxb:id/iv_ok')
        ele_iv_ok.click()
        time.sleep(2)

    except:
        pass
    if need_start:
        iv_start(driver)


def main():
    driver = get_driver()
    time.sleep(1)
    skip_ad(driver)
    time.sleep(0.5)
    iv_start(driver)
    time.sleep(1)

    while True:
        """
        如果找到下一关
            iv_start(driver)
        如果找到双倍奖励
            点击双倍奖励
        """

        answer_question(driver)

        double_coin(driver)

        iv_start(driver)

    # driver.quit()


if __name__ == '__main__':
    main()
